package com.carrentalplatform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carrentalplatform.mapper.RentalOrderMapper;
import com.carrentalplatform.model.RentalOrder;
import com.carrentalplatform.model.Vehicle;
import com.carrentalplatform.service.RentalOrderService;
import com.carrentalplatform.service.VehicleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class RentalOrderServiceImpl extends ServiceImpl<RentalOrderMapper, RentalOrder> implements RentalOrderService {

    @Autowired
    private VehicleService vehicleService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOrder(Long userId, Long vehicleId, Long startShopId, Long endShopId, 
                           LocalDateTime startTime, LocalDateTime endTime) {
        // 获取车辆信息
        Vehicle vehicle = vehicleService.getById(vehicleId);
        if (vehicle == null) {
            return null;
        }
        
        // 检查车辆是否可租
        if (vehicle.getStatus() != 1) {
            return null;
        }
        
        // 计算租车天数和总价
        long days = Duration.between(startTime, endTime).toDays();
        if (days < 1) {
            days = 1; // 不足1天按1天计算
        }
        
        BigDecimal totalPrice = vehicle.getDailyPrice().multiply(new BigDecimal(days));
        
        // 创建订单
        RentalOrder order = new RentalOrder();
        order.setUserId(userId);
        order.setVehicleId(vehicleId);
        order.setStartShopId(vehicle.getShopId());
        order.setEndShopId(vehicle.getShopId());
        order.setStartTime(startTime);
        order.setEndTime(endTime);
        order.setTotalPrice(totalPrice);
        order.setStatus(0); // 未完成
        order.setCreateTime(LocalDateTime.now());
        
        // 保存订单
        this.save(order);
        
        // 更新车辆状态为已租
        vehicleService.updateVehicleStatus(vehicleId, 2);
        
        return order.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completeOrder(Long orderId) {
        RentalOrder order = this.getById(orderId);
        if (order == null || order.getStatus() != 0) {
            return false;
        }
        
        // 更新订单状态
        order.setStatus(1); // 已完成
        this.updateById(order);
        
        // 更新车辆状态为可租
        vehicleService.updateVehicleStatus(order.getVehicleId(), 1);
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelOrder(Long orderId) {
        RentalOrder order = this.getById(orderId);
        if (order == null || order.getStatus() != 0) {
            return false;
        }
        
        // 更新车辆状态为可租
        vehicleService.updateVehicleStatus(order.getVehicleId(), 1);
        
        // 删除订单
        return this.removeById(orderId);
    }

    @Override
    public IPage<RentalOrder> getUserOrders(Long userId, int page, int size) {
        Page<RentalOrder> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<RentalOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RentalOrder::getUserId, userId);
        queryWrapper.orderByDesc(RentalOrder::getCreateTime);
        
        return this.page(pageParam, queryWrapper);
    }

    @Override
    public IPage<RentalOrder> getShopOrders(Long shopId, int page, int size) {
        Page<RentalOrder> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<RentalOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RentalOrder::getStartShopId, shopId)
                   .or()
                   .eq(RentalOrder::getEndShopId, shopId);
        queryWrapper.orderByDesc(RentalOrder::getCreateTime);
        
        return this.page(pageParam, queryWrapper);
    }
    
    @Override
    public List<RentalOrder> getAllOrders() {
        LambdaQueryWrapper<RentalOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(RentalOrder::getCreateTime);
        return this.list(queryWrapper);
    }
    
    @Override
    public RentalOrder findById(Long id) {
        return this.getById(id);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOrderStatus(Long id, String status) {
        RentalOrder order = this.getById(id);
        if (order == null) {
            return false;
        }
        
        // Convert string status to integer
        int statusCode;
        switch (status.toLowerCase()) {
            case "processing":
                statusCode = 0;
                break;
            case "completed":
                statusCode = 1;
                // If order is completed, update vehicle status to available
                vehicleService.updateVehicleStatus(order.getVehicleId(), 1);
                break;
            case "cancelled":
                statusCode = 2;
                // If order is cancelled, update vehicle status to available
                vehicleService.updateVehicleStatus(order.getVehicleId(), 1);
                break;
            default:
                return false;
        }
        
        order.setStatus(statusCode);
        return this.updateById(order);
    }
}